Implement LWG2577: {shared,unique}_lock</tt> should use std::addressof git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@263506 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/__mutex_base b/include/__mutex_base index b019b47..6165023 100644 --- a/include/__mutex_base +++ b/include/__mutex_base 
@@ -109,24 +109,24 @@  unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}  _LIBCPP_INLINE_VISIBILITY  explicit unique_lock(mutex_type& __m) - : __m_(&__m), __owns_(true) {__m_->lock();} + : __m_(addressof(__m)), __owns_(true) {__m_->lock();}  _LIBCPP_INLINE_VISIBILITY  unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), __owns_(false) {} + : __m_(addressof(__m)), __owns_(false) {}  _LIBCPP_INLINE_VISIBILITY  unique_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), __owns_(__m.try_lock()) {} + : __m_(addressof(__m)), __owns_(__m.try_lock()) {}  _LIBCPP_INLINE_VISIBILITY  unique_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), __owns_(true) {} + : __m_(addressof(__m)), __owns_(true) {}  template <class _Clock, class _Duration>  _LIBCPP_INLINE_VISIBILITY  unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) - : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} + : __m_(addressof(__m)), __owns_(__m.try_lock_until(__t)) {}  template <class _Rep, class _Period>  _LIBCPP_INLINE_VISIBILITY  unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) - : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} + : __m_(addressof(__m)), __owns_(__m.try_lock_for(__d)) {}  _LIBCPP_INLINE_VISIBILITY  ~unique_lock()  { 
diff --git a/include/shared_mutex b/include/shared_mutex index dcb9394..45e7fd0 100644 --- a/include/shared_mutex +++ b/include/shared_mutex 
@@ -319,25 +319,25 @@    _LIBCPP_INLINE_VISIBILITY  explicit shared_lock(mutex_type& __m) - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(true)  {__m_->lock_shared();}    _LIBCPP_INLINE_VISIBILITY  shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(false)  {}    _LIBCPP_INLINE_VISIBILITY  shared_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(__m.try_lock_shared())  {}    _LIBCPP_INLINE_VISIBILITY  shared_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(true)  {}   @@ -345,7 +345,7 @@  _LIBCPP_INLINE_VISIBILITY  shared_lock(mutex_type& __m,  const chrono::time_point<_Clock, _Duration>& __abs_time) - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(__m.try_lock_shared_until(__abs_time))  {}   @@ -353,7 +353,7 @@  _LIBCPP_INLINE_VISIBILITY  shared_lock(mutex_type& __m,  const chrono::duration<_Rep, _Period>& __rel_time) - : __m_(&__m), + : __m_(addressof(__m)),  __owns_(__m.try_lock_shared_for(__rel_time))  {}   
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp index 15c193c..bd707bb 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp 
@@ -18,17 +18,33 @@    #include <shared_mutex>  #include <cassert> +#include "nasty_containers.hpp"   -std::shared_timed_mutex m0; -std::shared_timed_mutex m1;    int main()  { - std::shared_lock<std::shared_timed_mutex> lk0(m0); - std::shared_lock<std::shared_timed_mutex> lk1(m1); + { + typedef std::shared_timed_mutex M; +	M m0; +	M m1; + std::shared_lock<M> lk0(m0); + std::shared_lock<M> lk1(m1);  lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0));  assert(lk1.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; +	M m0; +	M m1; + std::shared_lock<M> lk0(m0); + std::shared_lock<M> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp index 4f4f6a5..c29a3fb 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp 
@@ -18,14 +18,28 @@    #include <shared_mutex>  #include <cassert> +#include "nasty_containers.hpp"    int main()  { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk0(m); - std::shared_lock<std::shared_timed_mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::shared_lock<M> lk0(m); + std::shared_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::shared_lock<M> lk0(m); + std::shared_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp index 9952102..341f0ce 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp 
@@ -18,12 +18,24 @@    #include <shared_mutex>  #include <cassert> +#include "nasty_containers.hpp"    int main()  { - std::shared_timed_mutex m; - m.lock_shared(); - std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp index d81796b..5fbb724 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp 
@@ -18,11 +18,22 @@    #include <shared_mutex>  #include <cassert> +#include "nasty_containers.hpp"    int main()  { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp index 4f47744..8d864ea 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp 
@@ -16,16 +16,18 @@  #include <mutex>  #include <cassert>   -std::mutex m0; -std::mutex m1; -  int main()  { - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; +	M m0; +	M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1);  lk1 = lk0;  assert(lk1.mutex() == &m0);  assert(lk1.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp index 4888fe9..0673021 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp 
@@ -16,14 +16,16 @@  #include <mutex>  #include <cassert>   -std::mutex m; -  int main()  { - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = lk0; + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = lk0;  assert(lk.mutex() == &m);  assert(lk.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp index 4dff853..e5db685 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp 
@@ -17,19 +17,34 @@    #include <mutex>  #include <cassert> - -std::mutex m0; -std::mutex m1; +#include "nasty_containers.hpp"    int main()  {  #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; +	M m0; +	M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1);  lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0));  assert(lk1.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; +	M m0; +	M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + }  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp index aa640ee..427deab 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp 
@@ -17,17 +17,30 @@    #include <mutex>  #include <cassert> - -std::mutex m; +#include "nasty_containers.hpp"    int main()  {  #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == true);  assert(lk0.mutex() == nullptr);  assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + }  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp index 9c3a7b6..20f7d24 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp 
@@ -17,12 +17,24 @@    #include <mutex>  #include <cassert> +#include "nasty_containers.hpp"    int main()  { - std::mutex m; + { + typedef std::mutex M; + M m;  m.lock(); - std::unique_lock<std::mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + }  } 
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp index bf62231..242dacb 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp 
@@ -17,11 +17,22 @@    #include <mutex>  #include <cassert> +#include "nasty_containers.hpp"    int main()  { - std::mutex m; - std::unique_lock<std::mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m));  assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + }  } 
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html index 0445145..0b9023b 100644 --- a/www/cxx1z_status.html +++ b/www/cxx1z_status.html 
@@ -223,7 +223,7 @@ 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2574">2574</a></td><td>[fund.ts.v2] <tt>std::experimental::function::operator=(F&amp;&amp;)</tt> should be constrained</td><td>Jacksonville</td><td></td></tr> 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2575">2575</a></td><td>[fund.ts.v2] <tt>experimental::function::assign</tt> should be removed</td><td>Jacksonville</td><td></td></tr> 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2576">2576</a></td><td><tt>istream_iterator</tt> and <tt>ostream_iterator</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td></td></tr> -	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2577">2577</a></td><td><tt>{shared,unique}_lock</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td></td></tr> +	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2577">2577</a></td><td><tt>{shared,unique}_lock</tt> should use <tt>std::addressof</tt></td><td>Jacksonville</td><td>Complete</td></tr> 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2579">2579</a></td><td>Inconsistency wrt Allocators in <tt>basic_string</tt> assignment vs. <tt>basic_string::assign</tt></td><td>Jacksonville</td><td>Complete</td></tr> 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2581">2581</a></td><td>Specialization of <tt>&lt;type_traits&gt;</tt> variable templates should be prohibited</td><td>Jacksonville</td><td>Complete</td></tr> 	<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2582">2582</a></td><td>&sect;[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits</td><td>Jacksonville</td><td></td></tr>